package com.mall.pay.services;

import com.mall.commons.tool.exception.BizException;
import com.mall.order.OrderCoreService;
import com.mall.order.constant.OrderRetCode;
import com.mall.order.dto.PayOrderSuccessRequest;
import com.mall.order.dto.PayOrderSuccessResponse;
import com.mall.pay.PayCoreService;
import com.mall.pay.constants.PayResultEnum;
import com.mall.pay.constants.PayReturnCodeEnum;
import com.mall.pay.dal.entitys.Payment;
import com.mall.pay.dal.persistence.PaymentMapper;
import com.mall.pay.dto.PaymentRequest;
import com.mall.pay.dto.alipay.AlipayQueryRetResponse;
import com.mall.pay.dto.alipay.AlipaymentResponse;
import com.mall.pay.utils.ExceptionProcessorUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;

/**
 * @Description:
 * @Author: JK
 * @Date: create in 2021/7/26 23:59
 */
@Slf4j
@Service
public class PayCoreServiceImpl implements PayCoreService {
    @Autowired
    PayHelper payHelper;

    @Autowired
    PaymentMapper paymentMapper;

    @Reference(timeout = 3000, check = false)
    OrderCoreService orderCoreService;

    @Override
    public AlipaymentResponse aliPay(PaymentRequest request) {
        AlipaymentResponse alipaymentResponse = new AlipaymentResponse();

        request.requestCheck();

        String qrCodeName = payHelper.test_trade_precreate(request);
        if (qrCodeName == null) {
            // 获取二维码请求失败
            alipaymentResponse.setCode(PayReturnCodeEnum.GET_CODE_FALIED.getCode());
            alipaymentResponse.setMsg(PayReturnCodeEnum.GET_CODE_FALIED.getMsg());
            return alipaymentResponse;
        }

        // 获取二维码请求成功
        log.info("成功获取二维码：" + qrCodeName);
        // 向tb_payment中插入一条支付记录
        Date currentDate = new Date();
        Payment payment = new Payment();
        payment.setStatus(PayResultEnum.PAY_PROCESSING.getCode());
        payment.setOrderId(request.getOrderId());
        payment.setProductName(request.getSubject());
        payment.setPayerAmount(request.getTotalFee());
        payment.setPayNo(request.getTradeNo());
        payment.setPayerUid(request.getUserId());
        payment.setPayerName(request.getUsername());
        payment.setOrderAmount(request.getOrderFee());
        payment.setPayWay(request.getPayChannel());
        payment.setRemark("支付宝支付");
        payment.setCreateTime(currentDate);
        payment.setUpdateTime(currentDate);

        int affectedRows = paymentMapper.insertSelective(payment);
        if (affectedRows != 1) {
            throw new BizException(PayReturnCodeEnum.DB_EXCEPTION.getCode(), PayReturnCodeEnum.DB_EXCEPTION.getMsg());
        }

        alipaymentResponse.setCode(PayReturnCodeEnum.SUCCESS.getCode());
        alipaymentResponse.setMsg(PayReturnCodeEnum.SUCCESS.getMsg());
        alipaymentResponse.setQrCode(qrCodeName);

        return alipaymentResponse;
    }

    @Override
    public AlipayQueryRetResponse queryAlipayRet(PaymentRequest paymentRequest) {
        AlipayQueryRetResponse alipayQueryRetResponse = new AlipayQueryRetResponse();

        paymentRequest.requestCheck();

        String orderId = paymentRequest.getOrderId();
        Date currentDate = new Date();

        // 首先根据订单id查询tb_payment表中，订单的支付记录
        Example paymentExample = new Example(Payment.class);
        paymentExample.createCriteria()
                .andEqualTo("orderId", orderId);
        List<Payment> payments = paymentMapper.selectByExample(paymentExample);

        // 遍历订单的所有支付记录，查找订单是否有支付成功的记录
        for (Payment payment : payments) {
            String outTradeNo = payment.getPayNo();
            if (PayResultEnum.PAY_SUCCESS.getCode().equals(payment.getStatus())) {
                // 订单支付成功，返回支付成功的响应
                log.info("orderId: " + orderId + "-outTradeNo: " + outTradeNo + "，支付成功！");
                alipayQueryRetResponse.setCode(PayReturnCodeEnum.SUCCESS.getCode());
                alipayQueryRetResponse.setMsg(PayReturnCodeEnum.SUCCESS.getMsg());
                return alipayQueryRetResponse;
            }
        }

        // 遍历订单的所有支付记录，查询支付记录的支付情况
        for (Payment payment : payments) {
            String outTradeNo = payment.getPayNo();
            log.info("outTradeNo: " + outTradeNo + "，开始查询支付结果...");

            // 该支付记录未支付成功，重新查询该支付记录是否支付成功
            boolean payResult = payHelper.test_trade_query(outTradeNo);

            if (payResult) {
                // 订单支付成功
                //1.修改tb_payment表中，对应的支付记录的支付状态为PAY_SUCCESS("2","支付成功")，
                //  修改支付成功时间pay_success_time，支付完成时间complete_time，更新时间update_time
                Payment paymentToUpdate = new Payment();
                paymentToUpdate.setStatus(PayResultEnum.PAY_SUCCESS.getCode());
                paymentToUpdate.setPaySuccessTime(currentDate);
                paymentToUpdate.setCompleteTime(currentDate);
                paymentToUpdate.setUpdateTime(currentDate);
                Example example = new Example(Payment.class);
                example.createCriteria()
                        .andEqualTo("payNo", outTradeNo);
                int updatePaymentAffectedRows = paymentMapper.updateByExampleSelective(paymentToUpdate, example);
                log.info("orderId: " + orderId + "-outTradeNo: " + outTradeNo + "，成功修改订单状态！");
                System.out.println("updatePaymentAffectedRows = " + updatePaymentAffectedRows);

                //2.修改tb_order表中，订单的status，update_time，payment_time(远程调用orderService服务)
                //3.扣减订单中所有商品的锁定库存(远程调用orderService服务)
                PayOrderSuccessRequest payOrderSuccessRequest = new PayOrderSuccessRequest();
                payOrderSuccessRequest.setOrderId(orderId);
                PayOrderSuccessResponse payOrderSuccessResponse = orderCoreService.payOrderSuccess(payOrderSuccessRequest);

                // 如果成功修改订单状态和锁定库存，则返回支付成功的响应；否则，返回数据库异常
                if (OrderRetCode.SUCCESS.getCode().equals(payOrderSuccessResponse.getCode())) {
                    //4.返回支付成功的响应
                    log.info("orderId: " + orderId + "-outTradeNo: " + outTradeNo + "，支付成功！");
                    alipayQueryRetResponse.setCode(PayReturnCodeEnum.SUCCESS.getCode());
                    alipayQueryRetResponse.setMsg(PayReturnCodeEnum.SUCCESS.getMsg());
                } else {
                    // 如果成功修改订单状态和锁定库存，返回数据库异常
                    alipayQueryRetResponse.setCode(PayReturnCodeEnum.DB_EXCEPTION.getCode());
                    alipayQueryRetResponse.setCode(PayReturnCodeEnum.DB_EXCEPTION.getMsg());
                }
                return alipayQueryRetResponse;
            } else {
                // 订单支付失败
                //1.修改tb_payment表中，对应的支付记录的支付状态，为PAY_FAIL("3","支付失败")，
                //  修改支付完成时间complete_time，更新时间update_time
                Payment paymentToUpdate = new Payment();
                paymentToUpdate.setStatus(PayResultEnum.PAY_FAIL.getCode());
                paymentToUpdate.setCompleteTime(currentDate);
                paymentToUpdate.setUpdateTime(currentDate);
                Example example = new Example(Payment.class);
                example.createCriteria()
                        .andEqualTo("orderId", orderId);
                int updatePaymentAffectedRows = paymentMapper.updateByExampleSelective(paymentToUpdate, example);
                log.info("orderId: " + orderId + "-outTradeNo: " + outTradeNo + "，支付失败！");
                System.out.println("updatePaymentAffectedRows = " + updatePaymentAffectedRows);
            }
        }
        //2.返回支付失败的响应
        alipayQueryRetResponse.setCode(PayReturnCodeEnum.PAYMENT_PROCESSOR_FAILED.getCode());
        alipayQueryRetResponse.setMsg(PayReturnCodeEnum.PAYMENT_PROCESSOR_FAILED.getMsg());

        return alipayQueryRetResponse;
    }
}
